//
// Created by Win10 on 2022/10/16.
//
#include "cl_list.h"
#include<iostream>
#include<algorithm>

using namespace std;

bool InitList(LinkList &L) {
    L = (LNode *) malloc(sizeof(LNode));//分配一个头节点
    if (L == nullptr) return false;
    L->next = L;
    return true;
}

LNode *GetElem(LinkList L, int i) {
    if (i < 0) return nullptr;
    if (i == 0) return L;
    int j = 1;
    LNode *p = L->next;
    while (p != L && j < i) {
        p = p->next;
        j++;
    }
    return p;
}

LNode *LocateElem(LinkList L, int e) {
    LNode *p = L->next;
    while (p != L && p->data != e) {
        p = p->next;
    }
    if (p->data == e) return p;
    return nullptr;
}

int Length(LinkList L) {
    int len = 0;
    LNode *p = L;
    while (p->next != L) {
        len++;
        p = p->next;
    }
    return len;
}

bool ListInsert(LinkList &L, int i, int e) {
    if (i < 1) return false;
    LNode *p = GetElem(L, i - 1);
    if (!p) return false;
    return InsertNextNode(p, e);
}

bool InsertNextNode(LNode *p, int e) {
    if (!p) return false;
    auto s = (LNode *) malloc(sizeof(LNode));
    if (!s) return false;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

bool InsertPriorNode(LNode *p, int e) {
    if (!p) return false;
    auto s = (LNode *) malloc(sizeof(LNode));
    if (!s) return false;
    s->next = p->next;
    p->next = s;
    s->data = p->data;
    p->data = e;
    return true;
}

bool InsertPriorNode(LNode *p, LNode *s) {
    if (!p || !s) return false;
    s->next = p->next;
    p->next = s;
    swap(s->data, p->data);
    return true;
}

bool ListDelete(LinkList &L, int i, int &e) {
    if (i < 1) return false;
    LNode *p = GetElem(L, i - 1);
    if (p == nullptr || p->next == L) return false;
    LNode *q = p->next;
    e = q->data;
    p->next = q->next;
    free(q);
    return true;
}

LinkList List_TailInsert(LinkList &L) {
    InitList(L);
    LNode *s, *r = L;    //r表示表尾指针
    int x;
    while (cin >> x) {
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;
        r->next = s;
        r = s;
    }
    r->next = L;
    return L;
}

bool DeleteNode(LinkList &L, LNode *p) {
    LNode *q = p->next;
    p->data = q->data;
    p->next = q->next;

    if (L == q) {
        L = p;
    }
    free(q);
    return true;
}

LinkList List_HeadInsert(LinkList &L) {
    InitList(L);
    LNode *s, *r = L;
    int x;
    bool isFirst = true;
    while (cin >> x) {
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;
        if (isFirst) {
            r = s;
            isFirst = false;
        }
    }
    r->next = L;
    return L;
}

bool Empty(LinkList L) {
    if (L->next == L) {
        return true;
    }
    return false;
}

bool isTail(LinkList L, LNode *p) {
    if (p->next == L) return true;
    return false;
}

void print(LinkList L) {
    LNode *s = L->next;
    while (s != L) {

        cout << s->data << " ";
        s = s->next;
    }
    cout << endl;
}

int main() {

    LinkList L;
    //List_HeadInsert(L);
    //cout << "头插法的结果" << endl;
    //print(L);
    List_TailInsert(L);
    cout << "尾插法的结果" << endl;
    print(L);
    cout << "链表的第1个元素：" << GetElem(L, 1)->data << endl;
    cout << "链表的第5个元素：" << GetElem(L, 5)->data << endl;
    cout << "链表的长度：" << Length(L) << endl;
    int e;

    ListDelete(L, 5, e);
    cout << "删除的第5个元素是：" << e << endl;
    cout << "当前的链表" << endl;
    print(L);
    ListInsert(L, 5, e);
    cout << "插入的第5个元素是：" << e << endl;
    cout << "当前的链表" << endl;
    print(L);

    ListDelete(L, 1, e);
    cout << "删除的第1个元素是：" << e << endl;
    cout << "当前的链表" << endl;
    print(L);
    ListInsert(L, 1, e);
    cout << "插入的第1个元素是：" << e << endl;
    cout << "当前的链表" << endl;
    print(L);

    LNode *s = LocateElem(L, 5);
    DeleteNode(L, s);
    print(L);

    return 0;
}
/*
输入样例：
1 2 3 4 5
*/